package grape.auth.rest.service.impl;

import cn.hutool.json.JSONUtil;
import grape.base.rest.client.user.UserClient;
import grape.common.AbstractLoginUser;
import grape.common.service.common.dataconstraint.RawDataConstraint;
import grape.common.service.loginuser.LoginUser;
import grape.common.tools.ToolService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.core.authority.AuthorityUtils;
import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.security.core.userdetails.UserDetailsService;
import org.springframework.security.core.userdetails.UsernameNotFoundException;
import org.springframework.stereotype.Component;

import java.util.*;
import java.util.stream.Collectors;

/**
 * 依赖base的登录，用在pc后台用户登录
 * Created by yangwei
 * Created at 2020/1/8 17:39
 */
@Component("userDetailsService")
public class UserDetailsServiceImpl implements UserDetailsService , ToolService {

    @Autowired
    private UserClient userClient;
    @Override
    public UserDetails loadUserByUsername(String identifier) throws UsernameNotFoundException {
        boolean superAdmin = false;
        Map<String,Object> details = userClient.details(identifier);
        if (details == null) {
            throw  new UsernameNotFoundException("identifier=["+ identifier +"],未获取到用户id");
        }
        String userId = (String) details.get("id");
        Set<String> authority = new HashSet<>();
        authority.add("user");
        List<String> roles = (List<String>) details.get("roles");
        List<String> funcs = (List<String>) details.get("funcs");
        if (!isEmpty(roles)) {
            for (String role : roles) {
                if (isEqual(role, AbstractLoginUser.superadminCode)) {
                    superAdmin = true;
                    break;
                }
            }
            authority.addAll(roles.stream().map(role-> "ROLE_" + role).collect(Collectors.toSet()));
        }
        if (!isEmpty(funcs)) {
            authority.addAll(funcs);
        }
        List<RawDataConstraint> rawDataConstraints = new ArrayList<>();
        Object dataConstraint = details.get("rawDataConstraint");
        if (dataConstraint != null) {
            if (!((List) dataConstraint).isEmpty()) {
                rawDataConstraints = JSONUtil.toList(JSONUtil.parseArray(dataConstraint), RawDataConstraint.class);
            }
        }
        LoginUser loginUser = new LoginUser(userId,
                (String) details.get("pwd"),
                true,
                true,
                true,
                !(Boolean) details.get("isLock"),
                AuthorityUtils.createAuthorityList(authority.toArray(new String[0])),
                rawDataConstraints
        );
        loginUser.setId(userId);
        loginUser.setSuperAdmin(superAdmin);
        loginUser.setIdentifierTypeDictId((String) details.get("identifierTypeDictId"));
        return loginUser;
    }
}
